package top.kaoshanji.p2ch07a;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;

/**
 * 代码清单-p2ch07a-219页a：使用幽灵引用的内存分配方式
 * author kaoshanji
 * ^_^
 * create time 2025/1/20 17:06
 */
public class PhantomReferenceExample02 {

    private static final Logger logger = LogManager.getLogger(PhantomReferenceExample02.class);

    private byte[] data = null;

    private ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

    private Reference<? extends byte[]> ref = null;

    public static void main(String[] args) {
        logger.info("...代码清单-p2ch07a-219页a：使用幽灵引用的内存分配方式...");

        PhantomReferenceExample02 example = new PhantomReferenceExample02();
        int runs = 20;
        int size = 5 * 1000 * 1000;
        for (int i = 0; i < runs; i++) {
            example.get(size + i);
        }

    }

    public byte[] get(int size) {
        if (ref == null) {
            data = new byte[size];
            ref = new PhantomReference<>(data, queue);
        } else {
            data = null;
            System.gc();
            try {
                ref = queue.remove();
                ref.clear();
                ref = null;
                System.gc();
                data = new byte[size];
                ref = new PhantomReference<>(data, queue);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

}
